package test.serverframe.armc.server.manager.controller;

import com.github.pagehelper.PageInfo;
import com.microcore.entity.InvokeTrigger;
import com.microcore.service.TriggerService;

import io.swagger.annotations.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import test.serverframe.armc.server.manager.common.ResultDtoUtil;
import test.serverframe.armc.server.manager.common.exception.ExceptionHandle;
import test.serverframe.armc.server.manager.controller.vo.InvokeDetailVo;
import test.serverframe.armc.server.manager.controller.vo.InvokeRecordPage;
import test.serverframe.armc.server.manager.controller.vo.TaskInvokeVo;
import test.serverframe.armc.server.manager.domain.ConfigManager;
import test.serverframe.armc.server.manager.domain.Tag;
import test.serverframe.armc.server.manager.domain.params.AddTaskInvokeParams;
import test.serverframe.armc.server.manager.domain.params.HistoryPageParams;
import test.serverframe.armc.server.manager.domain.params.InvokePage;
import test.serverframe.armc.server.manager.domain.params.InvokePageParams;
import test.serverframe.armc.server.manager.domain.TaskInvoke;
import test.serverframe.armc.server.manager.domain.params.UpdateInvokeStatusParams;
import test.serverframe.armc.server.manager.dto.ResultDto;
import test.serverframe.armc.server.manager.service.TaskService;
import test.serverframe.armc.server.manager.service.exec.ExecutorEnterService;
import test.serverframe.armc.server.manager.service.impl.ConfigManagerService;
import test.serverframe.armc.server.manager.service.impl.InvokeRecordService;
import test.serverframe.armc.server.manager.service.impl.InvokeTaskRecordServiceImpl;
import test.serverframe.armc.server.manager.service.impl.TagServiceImpl;
import test.serverframe.armc.server.manager.service.impl.TaskInvokeServiceImpl;

import javax.validation.Valid;

import java.util.Collections;
import java.util.List;

/**
 * @Description 任务调度controller
 * @Author LSY
 * @Date 2018/10/10 14:45
 * @ClassName test.serverframe.armc.server.manager.controller.TaskInvokeController
 */
@CrossOrigin(origins = "*")
@Api("任务调度")
@Validated
@RequestMapping("/taskInvoke")
@RestController
public class TaskInvokeController {

    private Logger logger = LoggerFactory.getLogger(TaskInvokeController.class);
    
    @Autowired
    private TaskInvokeServiceImpl taskInvokeService;

    @Autowired
    private ExceptionHandle<PageInfo<InvokePage>> exceptionHandle;
    
    @Autowired
    private InvokeRecordService invokeRecordService;
    
    @Autowired
    private InvokeTaskRecordServiceImpl invokeTaskRecordService;
    
    @Autowired
    private TriggerService triggerService;
    
    @Autowired
	private TaskService taskService;
    
    @Autowired
    private ExecutorEnterService executorEnterService;
    
    @Autowired
    private TagServiceImpl tagService;
    
    @Autowired
    private ConfigManagerService configManagerService;

    /**
     * @Descripttion 任务调度分页、筛选查询
     * @Author UaenaSA
     * @Date 2018/12/13 10:45
     * @Param [pageNum 页码, pageSize 分页大小, taskInvoke 任务调度实体]
     * @Return
     **/
    @GetMapping("taskInvokePages")
    @ApiOperation(notes = "任务调度分页、筛选查询", value = "任务调度分页、筛选查询", httpMethod = "GET")
    public ResultDto<PageInfo<InvokePage>> taskPages(@ModelAttribute @Valid InvokePageParams params) {
        ResultDto<PageInfo<InvokePage>> result;
        try {

            PageInfo<InvokePage> mbrValues = taskInvokeService.pageFind(params.getPageNum(), params.getPageSize(), params);
            for (InvokePage i:mbrValues.getList()){
                List list =invokeTaskRecordService.selectTaskImplement(i.getLastInvokeRecordId());
                Collections.reverse(list);
                i.setTasks(list);
            }
            result = ResultDtoUtil.success(mbrValues);
        } catch (Exception ex) {
            result = exceptionHandle.exceptionGet(ex);
        }
        return result;
    }

    /**
     * @Descripttion 任务调度新增
     * @Author LSY
     * @Date 2018/10/10 17:19
     * @Param [taskInvoke 任务调度实体]
     * @Return
     **/
    @PostMapping("/addTaskInvoke")
    @ApiOperation(notes = "任务调度新增", value = "任务调度新增", httpMethod = "POST")
    public ResultDto<String> addTaskInvoke(@ApiParam @RequestBody @Valid AddTaskInvokeParams params) {
        ResultDto<String> result = null;
        try {
            TaskInvoke invoke = new TaskInvoke();
            invoke.setInvokeName(params.getInvokeName());
            TaskInvoke isRepeat = taskInvokeService.selectSelective(invoke);
            if (isRepeat == null) {
                taskInvokeService.addTaskInvoke(params);
                result = ResultDtoUtil.success();
            } else {
                result = ResultDtoUtil.error(500, "任务调度名称不能重复");
                return result;
            }
        } catch (Exception ex) {
            result = ResultDtoUtil.error(500, "任务调度新增错误");
            logger.error("任务调度新增错误", ex);
        }
        return result;
    }

    /**
     * @Descripttion 修改任务调度
     * @Author LSY
     * @Date 2018/10/11 11:29
     * @Param [taskInvoke 任务调度实体]
     * @Return
     **/
    @PostMapping("/updateTaskInvoke")
    @ApiOperation(notes = "任务调度修改", value = "任务调度修改", httpMethod = "POST")
    public ResultDto<Integer> updateTaskInvoke(@ApiParam @RequestBody @Valid AddTaskInvokeParams taskInvoke) {
        ResultDto<Integer> result;
        try {
            int i = taskInvokeService.updateTaskInvoke(taskInvoke);
            result = ResultDtoUtil.success(i);
        } catch (Exception ex) {
            result = ResultDtoUtil.error(500, "任务调度新增错误");
            logger.error("修改任务调度失败", ex);
        }
        return result;
    }
    /**
     * 获取当前调度详情（修改）
     * @author yegui  
     * @date 2018年12月15日  
     * @param taskInvokeId
     * @return
     * ResultDto<TaskInvoke>
     */
    @GetMapping("/getInvokeDetail/{taskInvokeId}")
    @ApiOperation(notes = "获取当前调度详情（修改）", value = "获取当前调度详情(修改)", httpMethod = "GET")
    public ResultDto<TaskInvokeVo> getInvokeDetail(@ApiParam @PathVariable @Valid String taskInvokeId) {
    	ResultDto<TaskInvokeVo> result = null;
    	try {
    		TaskInvokeVo taskInvoke = taskInvokeService.findById(taskInvokeId);
    		List<InvokeTrigger> triggers = triggerService.getTriggersByInvokeId(taskInvokeId);
     		List<InvokeDetailVo> voList = taskService.findTaskByTaskInvokeId(taskInvokeId);
     		List<Tag> tags = tagService.findTagsByInvokeId(taskInvokeId);
     		taskInvoke.setTags(tags);
    		taskInvoke.setTaskVoList(voList);
    		taskInvoke.setTriggers(triggers);
    		result = ResultDtoUtil.success(taskInvoke);
		} catch (Exception e) {
			logger.error("获取历史调度详情失败", e);
			result = ResultDtoUtil.error(500, "获取历史调度详情失败");
		} 
    	
    	return result;
    }

    /**
     * @Descripttion 删除任务调度
     * @Author LSY
     * @Date 2018/10/11 10:12
     * @Param [taskInvoke 任务调度实体，只用传任务调度id集合]
     * @Return
     **/
    @PostMapping("/deleteInvoke")
    @ApiOperation(notes = "删除任务调度", value = "删除任务调度", httpMethod = "POST")
    public ResultDto<Integer> deleteInvoke(@ApiParam @RequestBody @Valid List<String> taskInvokeIds) {
        ResultDto<Integer> result;
        try {
        	taskInvokeService.deleteInvoke(taskInvokeIds);
            result = ResultDtoUtil.success();
        } catch (Exception ex) {
            result = ResultDtoUtil.error(500, "删除任务调度错误");
            logger.error("任务调度删除失败", ex);
        }
        return result;
    }

    /**
     * 获取历史调度详情分页
     * @author yegui  
     * @date 2018年12月15日  
     * @param params
     * @return
     * ResultDto<PageInfo<InvokeRecord>>
     */
    @PostMapping("/getHistoryInvokeDetail")
    @ApiOperation(notes = "获取历史调度详情", value = "获取历史调度详情", httpMethod = "POST")
    public ResultDto<PageInfo<InvokeRecordPage>> getHistoryInvokeDetail(@ApiParam @RequestBody @Valid HistoryPageParams params) {
    	ResultDto<PageInfo<InvokeRecordPage>> result = null;
    	try {
    		ConfigManager config = configManagerService.selectConfig();
    		params.setRecordDay(config.getRecordTime());
    		PageInfo<InvokeRecordPage> invokeRecordPage = invokeRecordService.pageFindToday(params.getPageNum(), params.getPageSize(), params);
    		result = ResultDtoUtil.success(invokeRecordPage);
		} catch (Exception e) {
			logger.error("获取历史调度详情失败", e);
			result = ResultDtoUtil.error(500, "获取历史调度详情失败");
		} 
    	
    	return result;
    }

    /**
     * 任务调度批量启用、禁用状态修改
     * @author yegui  
     * @date 2018年12月17日  
     * @param taskInvokeList
     * @return
     * ResultDto<Integer>
     */
    @PostMapping("/batchUpdateStatus")
    @ApiOperation(notes = "任务调度批量启用、禁用状态修改", value = "任务调度批量启用、禁用状态修改", httpMethod = "POST")
    public ResultDto<Integer> batchUpdateStatus(@ApiParam @RequestBody @Valid List<UpdateInvokeStatusParams> taskInvokeList) {
        ResultDto<Integer> result;
        try {
            taskInvokeService.batchUpdateStatus(taskInvokeList);
            result = ResultDtoUtil.success();
        } catch (Exception e) {
            logger.error("批量更新调度状态异常", e);
            result = ResultDtoUtil.error(500, "批量更新调度状态失败");
        }

        return result;
    }

    /**
     * @Author UaenaSA
     * @param ids 调度记录ID
     * @return
     */
    @DeleteMapping("/record/delete")
    @ApiOperation(notes = "批量删除历史记录", value = "批量删除历史记录")
    public ResultDto<Integer> deleteTask(@RequestBody List<String> ids) {
        ResultDto<Integer> result;
        try {
            ids.forEach(id -> {
                invokeRecordService.deleteRecord(id);
            });
            result = ResultDtoUtil.success();
        } catch (Exception ex) {
            result = ResultDtoUtil.error(500, "批量删除历史记录错误");
        }
        return result;
    }

    /**
     * 调度立即执行
     * @author yegui
     * @param id
     * @return
     */
    @PostMapping("/start")
    @ApiOperation(notes = "立即执行", value = "立即执行", httpMethod = "POST")
    public ResultDto<String> start(@ApiParam @RequestBody @Valid List<String> ids) {
    	ResultDto<String> result;
    	try {
    		ids.forEach( id -> {
    			executorEnterService.executorEnter(id, String.valueOf(false));
    		});
    		result = ResultDtoUtil.success();
		} catch (Exception e) {
			result = ResultDtoUtil.error(500, "立即执行失败");
			logger.error("立即执行失败", e);
		}
    	return result;
    }

}
